package com.ihr360.sharedservice.calendar.service.impl;


import cn.irenshi.core.utils.DateUtil;
import com.google.common.collect.Lists;
import com.ihr360.commons.lang.DateUtils;
import com.ihr360.sharedservice.calendar.dao.StatutoryVacationDao;
import com.ihr360.sharedservice.calendar.dto.StatutoryVacation;
import com.ihr360.sharedservice.calendar.service.StatutoryVacationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class StatutoryVacationServiceImpl implements StatutoryVacationService {

    @Autowired
    private StatutoryVacationDao statutoryVacationDaoImpl;

    @Override
    public List<StatutoryVacation> selectAll() {
        return statutoryVacationDaoImpl.findAll();
    }

    @Override
    public List<StatutoryVacation> selectAllStatutoryHoliday(Integer year, Integer month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        Date date = cal.getTime();
        return statutoryVacationDaoImpl.findByVacationDateAndVacationCategoryIn(date);
    }


    @Override
    public List<StatutoryVacation> getWorkingCalendar(Integer year, Integer month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        Date date = cal.getTime();
        return statutoryVacationDaoImpl.findStatutoryAndSupplementaryInMonth(date);
    }

    @Override
    public List<StatutoryVacation> selectAllWorkDayForStatutoryHoliday(Integer year, Integer month) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        Date date = cal.getTime();
        return statutoryVacationDaoImpl.findByVacationDateAndVacationCategory(date);
    }

    @Override
    public List<Boolean> findPermanentCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        List<StatutoryVacation> sVacationList = this.selectAllStatutoryHoliday(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1);
        List<StatutoryVacation> sWorkList = this.selectAllWorkDayForStatutoryHoliday(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1);

        List<Integer> restList = Lists.newArrayList();
        for (StatutoryVacation statutoryVacation : sVacationList) {
            if (statutoryVacation.getVacationDate() != null) {
                restList.add(DateUtil.getDay(statutoryVacation.getVacationDate()));
            }
        }

        List<Integer> workList = Lists.newArrayList();
        for (StatutoryVacation statutoryVacation : sWorkList) {
            if (statutoryVacation.getVacationDate() != null) {
                workList.add(DateUtil.getDay(statutoryVacation.getVacationDate()));
            }
        }

        List<Boolean> newWorkList = Lists.newArrayList();

        int day = DateUtil.getDay(DateUtil.getMaxDateInMonth(date));
        for (int i = 0; i < day; i++) {
            if (restList.indexOf(i + 1) > -1) {
                newWorkList.add(false);
            } else if (workList.indexOf(i + 1) > -1) {
                newWorkList.add(true);
            } else {
                calendar.set(Calendar.DAY_OF_MONTH, i + 1);
                newWorkList.add(calendar.get(Calendar.DAY_OF_WEEK) != 1 && calendar.get(Calendar.DAY_OF_WEEK) != 7);
            }
        }

        return newWorkList;
    }

    @Override
    public List<String> getStatutoryVacationBetweenMonth(Date startMonth, Date endMonth) {
        List<String> holidayList = Lists.newArrayList();
        int diff = DateUtil.getMonthsOfAge(startMonth, endMonth);
        if (diff > 0) {
            for (int i = 0; i < diff; i++) {
                Date date = DateUtil.getMonthByAddMonthly(startMonth, i);
                List<StatutoryVacation> statutoryVacationList = statutoryVacationDaoImpl.findByVacationDateAndVacationCategoryIn(date);
                holidayList.addAll(statutoryVacationList.stream().filter(statutoryVacation -> statutoryVacation.getVacationDate() != null
                        && statutoryVacation.getIsStatutoryHoliday() != null && statutoryVacation.getIsStatutoryHoliday())
                        .map(statutoryVacation -> DateUtils.formatDateStr(statutoryVacation.getVacationDate(), DateUtils.STANDARD_DATE_FORMAT_YMD))
                        .collect(Collectors.toList()));
            }
        }
        return holidayList;
    }

    @Override
    public List<StatutoryVacation> getStatutoryHolidayVacationBetweenDay(Date startDate, Date endDate) {
        return statutoryVacationDaoImpl.findByIsStatutoryHolidayAndVacationDateBetween(Boolean.TRUE, startDate, endDate);
    }
}
